package leilei.jace.com.tcpdemo2.service;

import org.greenrobot.eventbus.EventBus;

import java.net.InetSocketAddress;
import java.util.Iterator;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import leilei.jace.com.tcpdemo2.client.MainActivity;
import leilei.jace.com.tcpdemo2.text.ConstantValue;
import leilei.jace.com.tcpdemo2.text.FristTextEvent;
import leilei.jace.com.tcpdemo2.text.SmartCarProtocol;
import leilei.jace.com.tcpdemo2.util.LogUtil;
import leilei.jace.com.tcpdemo2.util.NettyConfig;

/**
 * Created by leilei on 2018/3/28.
 */

public class ServerHandler extends ChannelInboundHandlerAdapter {
    private int loss_connect_time = 0;

    /**
     * 客户端与服务端创建连接的时候调用
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端与服务端连接开始...");
        if (!NettyConfig.service_group.contains(ctx.channel())) {
            NettyConfig.service_group.add(ctx.channel());
        }
    }

    /**
     * 客户端与服务端断开连接时调用
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端与服务端连接关闭...");
        if (NettyConfig.service_group.contains(ctx.channel())) {
            NettyConfig.service_group.remove(ctx.channel());
        }
        ctx.close();
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {
                loss_connect_time++;
                System.out.println("5 秒没有接收到客户端的信息了");
                if (loss_connect_time > 2) {
                    System.out.println("关闭这个不活跃的channel");
//                    ctx.channel().close();
                }
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
            throws Exception {
        // 用于获取客户端发来的数据信息
        SmartCarProtocol body = (SmartCarProtocol) msg;
        System.out.println("Server接受的客户端的信息 :" + body.toString());
        if (ConstantValue.HEAD_HEART_BEAT.equals(new String(body.getContent()))) {
            LogUtil.e("Server接受的客户端的心跳数据", new String(body.getContent()) + "==" + ctx.channel().remoteAddress());
        } else {
            LogUtil.e("Server接受的客户端的信息", new String(body.getContent()) + "==" + ctx.channel().remoteAddress());
        }
        LogUtil.e("客户端的ip", ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostName() + "==");
        // 会写数据给客户端
        String str = new String(body.getContent());
        SmartCarProtocol response = new SmartCarProtocol(str.getBytes().length,
                str.getBytes());
        // 当服务端完成写操作后，关闭与客户端的连接
//        ctx.writeAndFlush(response)
//                .addListener(ChannelFutureListener.CLOSE);
        // 当有写操作时，不需要手动释放msg的引用
        // 当只有读操作时，才需要手动释放msg的引用
        EventBus.getDefault().post(new FristTextEvent("Service received:" + new String(body.getContent()) + ctx.channel().remoteAddress(), MainActivity.SERVICE_MESSAGE, 0));

        //服务端使用这个就能向 每个连接上来的客户端群发消息
        NettyConfig.service_group.writeAndFlush(response);
        Iterator<Channel> iterator = NettyConfig.service_group.iterator();
        while (iterator.hasNext()) {
            Channel channel = iterator.next();
            //打印出所有客户端的远程地址
//            LogUtil.e("打印出所有客户端的ip", ((InetSocketAddress)channel).getAddress().getHostName()+"==");
            LogUtil.e("打印出所有客户端的远程地址", channel.remoteAddress() + "==");
//            LogUtil.e("打印出所有客户端的远程地址", (iterator.next()).remoteAddress() + "==");
        }

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
